package groovy;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import groovy.lang.*;
import groovy.text.GStringTemplateEngine;
import groovy.text.SimpleTemplateEngine;
import groovy.text.Template;
import groovy.text.markup.MarkupTemplateEngine;
import groovy.text.markup.TemplateConfiguration;
import groovy.util.GroovyScriptEngine;
import groovy.util.ResourceException;
import groovy.util.ScriptException;
import org.codehaus.groovy.control.CompilerConfiguration;

import java.io.IOException;
import java.io.Reader;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

public class TestGroovyTemplate {
    private static GroovyClassLoader groovyClassLoader = null;

    public static void initGroovyClassLoader() {
        CompilerConfiguration config = new CompilerConfiguration();
        config.setSourceEncoding("UTF-8");
        // 设置该GroovyClassLoader的父ClassLoader为当前线程的加载器(默认)
        groovyClassLoader = new GroovyClassLoader(Thread.currentThread().getContextClassLoader(), config);
    }

    public static void main(String[] args) {
        try {
            test4();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static String sexFormat(Integer sex){
        if(sex==null){
            return "未知";
        }
        if(sex.equals(0)){
            return "男";
        }
        return "女";
    }

    public static void test3() throws Exception{
        String jsonTemplate = "{\"inpNo\":\"$inpNo\",\"name\":\"$name\",\"birthday\":\"$birthday\",\"sex\":\"${fn.sexFormat(sex)}\",\"odsOperate\":[<% for (item in odsOperate) { %>    {        \"icdCode\":\"$item.icdCode\",        \"surgeryCode\":\"$item.surgery_code\"    },<% } %>]<% for (item in odsZd) { %>    {        \"icdCode\":\"$item.icdCode\",        \"surgeryCode\":\"$item.surgery_code\"    },<% } %>}";
//        String jsonTemplate = "${fn.sexFormat(sex)}";
        String jsonSource = "{\"inpNo\":\"001\",\"name\":\"张三\",\"birthday\":\"2021-03-11\",\"sex\":1,\"odsOperate\":[{\"icdCode\":\"7777\",\"surgery_code\":\"6666\"},{\"icdCode\":\"2222\",\"surgery_code\":\"333\"}],\"odsZd\":[]}";
        JSONObject json = JSONObject.parseObject(jsonSource);
//        GroovyObject groovyObject = (GroovyObject) TestGroovyTemplate.class.getClassLoader().loadClass("groovy.JsonTemplateEngine").newInstance();
        GroovyScriptEngine scriptEngine = new GroovyScriptEngine("src/main/java/groovy/");
        scriptEngine.loadScriptByName("TemplateFunctionFacade.groovy");
        Class script = scriptEngine.loadScriptByName("JsonTemplateEngine2.groovy");
        Script instance = (Script) script.newInstance();
        Template template = (Template) instance.invokeMethod("createTemplate",jsonTemplate);
        Object[] objects = new Object[]{template,json};
        String jsonResult = (String) instance.invokeMethod("make",objects);
//        JsonTemplateEngine mar = new JsonTemplateEngine();
//        String jsonResult = mar.make(engine,json);
        System.out.println(jsonResult);
    }

    public void test1(){
        GStringTemplateEngine engine = new GStringTemplateEngine();
        String jsonTemplate = "{\"inpNo\":\"$inpNo\",\"name\":\"$name\",\"birthday\":\"$birthday\",\"sex\":\"$sexFormat($sex)\",\"odsOperate\":[<% for (item in odsOperate) { %>    {        \"icdCode\":\"$item.icdCode\",        \"surgeryCode\":\"$item.surgery_code\"    },<% } %>]<% for (item in odsZd) { %>    {        \"icdCode\":\"$item.icdCode\",        \"surgeryCode\":\"$item.surgery_code\"    },<% } %>}";
        Template template = null;
        try {
            template = engine.createTemplate(jsonTemplate);
        } catch (Exception e) {
            e.printStackTrace();
        }
        String jsonSource = "{\"inpNo\":\"001\",\"name\":\"张三\",\"birthday\":\"2021-03-11\",\"sex\":0,\"odsOperate\":[{\"icdCode\":\"7777\",\"surgery_code\":\"6666\"},{\"icdCode\":\"2222\",\"surgery_code\":\"333\"}],\"odsZd\":[]}";
        try {
            JSONObject json = JSONObject.parseObject(jsonSource);
//            json.put("sexFormat",groovy.text.GStringTemplateEngine.TestClosure.prettify);
            String jsonResult = template.make(json).toString();
            System.out.println(jsonResult);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public void test2(){
//        TemplateConfiguration templateConfiguration = new TemplateConfiguration();
//        templateConfiguration.setBaseTemplateClass(WanglyTemplate.class);
//        MarkupTemplateEngine engine = new MarkupTemplateEngine();
//        Map<String,Object> map = engine.getCompilerConfiguration().getJointCompilationOptions();
//        if(null==map){
//            map = new HashMap<>();
//        }
//        try {
//            map.put("sexFormat",TestGroovyTemplate.class.getMethod("sexFormat",Object.class));
//            engine.getCompilerConfiguration().setJointCompilationOptions(map);
//        } catch (NoSuchMethodException e) {
//            e.printStackTrace();
//        }
    }
    private static void test4() throws Exception {
        String templateStr = "[\n" +
                "  {\n" +
                "    \"code\":\"${nodeIds.get(0)}\",\n" +
                "    \"type\":\"START_NODE\",\n" +
                "    \"nextNode\":\"${nodeIds.get(1)}\",\n" +
                "    \"config\":\"\"\n" +
                "  },\n" +
                "  {\n" +
                "    \"code\":\"${nodeIds.get(1)}\",\n" +
                "    \"type\":\"RULE_REPOSITORY_JUDGE_NODE\",\n" +
                "    \"failNode\":\"${nodeIds.get(nodeIds.size() - 1)}\",\n" +
                "    \"passNode\":\"${nodeIds.get(2)}\",\n" +
                "    \"config\":\"\"\n" +
                "  },\n" +
                "  {\n" +
                "    \"code\":\"${nodeIds.get(2)}\",\n" +
                "    \"type\":\"RULE_QL_JUDGE_NODE\",\n" +
                "    \"failNode\":\"${nodeIds.get(3)}\",\n" +
                "    \"passNode\":\"${nodeIds.get(nodeIds.size() - 1)}\",\n" +
                "    \"config\":\"\\${patientInfo.insuranceTypeCode == 1}\"\n" +
                "  },\n" +
                "  {\n" +
                "    \"code\":\"${nodeIds.get(3)}\",\n" +
                "    \"type\":\"RULE_FILTER_INS_ACTION_NODE\",\n" +
                "    \"nextNode\":\"${nodeIds.get(4)}\",\n" +
                "    \"config\":\"\\${tempVar._currentOrderItem.isIns == 0}\"\n" +
                "  },\n" +
                "  {\n" +
                "    \"code\":\"${nodeIds.get(4)}\",\n" +
                "    \"type\":\"RULE_QL_EXPRESSION_ACTION_NODE\",\n" +
                "    \"nextNode\":\"${nodeIds.get(5)}\",\n" +
                "    \"config\":\"${config.ruleBaseExpression}\"\n" +
                "  },\n" +
                "  {\n" +
                "    \"code\":\"${nodeIds.get(5)}\",\n" +
                "    \"type\":\"CLEW_TEXT_BUILD_ACTION_NODE\",\n" +
                "    \"nextNode\":\"${nodeIds.get(nodeIds.size() -1)}\",\n" +
                "    \"config\":\"\"\n" +
                "  },\n" +
                "  {\n" +
                "    \"code\":\"${nodeIds.get(nodeIds.size() - 1)}\",\n" +
                "    \"type\":\"END_NODE\",\n" +
                "    \"config\":\"\\${fn.json(_ruleLog)}\"\n" +
                "  }\n" +
                "]";
        Map<String, Object> params = new HashMap<>();
        params.put("nodeIds", getNodeIds(10));
        params.put("config", RuleConfigTemplatesEnum.INSURANCE_1_2);
        GStringTemplateEngine engine = new GStringTemplateEngine();
        Template template = engine.createTemplate(templateStr);
        String jsonResult = template.make(params).toString();
        System.out.println(jsonResult);
    }

    private static List<String> getNodeIds(int size) {
        java.util.List<java.lang.String> nodeIds = Lists.newArrayList();
        for (int i = 0; i < size; i++) {
            nodeIds.add(UUID.randomUUID().toString());
        }
        return nodeIds;
    }
}
